package com.oig.sys.auth.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.oig.sys.query.support.module.FieldExpression;
import com.oig.sys.query.support.module.TableExpression;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 解析建模工具pdm
 * 生成通用查询 单表json
 */
public class PDMXmlUtil {


    private final static Namespace oNamespace = new Namespace("o", "object");
    private final static Namespace cNamespace = new Namespace("c", "collection");
    private final static Namespace aNamespace = new Namespace("a", "attribute");

    /**
     * 生成单表json
     */
    public static void buildJson(String path, List<Element> tableEles){
        for (Element tableElement : tableEles) {
            JSONObject jsonObject = new JSONObject() ;
            //表中文名
            //Element name = tableElement.element(new QName("Name", aNamespace));
            //表名
            Element code = tableElement.element(new QName("Code", aNamespace));

            JSONObject jsonTableObject = new JSONObject();
            jsonTableObject.put("field",code.getText()) ;
            jsonTableObject.put("rename","t1");
            jsonTableObject.put("join","master");
            jsonTableObject.put("on","");

            JSONArray jsonTableArray = new JSONArray();
            jsonTableArray.add(jsonTableObject);

            JSONArray jsonColumnArray = new JSONArray();
            Element columnsEls = tableElement.element(new QName("Columns", cNamespace));
            if (columnsEls==null){
                continue;
            }
            //解析column
            List<Element> columns = columnsEls.elements(new QName("Column", oNamespace));
            for (Element columnEle : columns) {
                //String columnId = columnEle.attribute("Id").getValue();
                Element cname = columnEle.element(new QName("Name", aNamespace));
                Element ccode = columnEle.element(new QName("Code", aNamespace));
//                Element cDataType = columnEle.element(new QName("DataType", aNamespace));
//                Element cLength = columnEle.element(new QName("Length", aNamespace));
//                Element cComment = columnEle.element(new QName("Comment", aNamespace));
               // Element nullable = columnEle.element(new QName("Column.Mandatory", aNamespace));
                JSONObject jsonFieldObject = new JSONObject();
                jsonFieldObject.put("field","t1."+ccode.getText());
                jsonFieldObject.put("rename",camelCaseName(ccode.getText()));
                jsonFieldObject.put("cnname",cname.getText());
                jsonFieldObject.put("options",new JSONObject());
                jsonColumnArray.add(jsonFieldObject);
            }

            jsonObject.put("fields", jsonColumnArray) ;
            jsonObject.put("tables", jsonTableArray);
            jsonObject.put("group_by", new ArrayList<>());
            String json = JSONObject.toJSONString(jsonObject,SerializerFeature.PrettyFormat);
            System.out.println(json);
            try {
                File jsonFile = new File(path,code.getText()+".json");
                //FileOutputStream fileOutputStream = new FileOutputStream(jsonFile);
                FileWriter fileWriter = new FileWriter(jsonFile);
                fileWriter.write(json);
                fileWriter.flush();
                fileWriter.close();
            } catch (Exception e){
                e.printStackTrace();
            }
        }

    }

    public static List<Map<String,Object>> buildExp(String path,List<Element> tableEles){
        List<Map<String,Object>> list = new ArrayList<>();
        for (Element tableElement : tableEles) {
            Map<String,Object> map = new HashMap<>() ;
            //表名
            Element code = tableElement.element(new QName("Code", aNamespace));

            TableExpression tableExpression = new TableExpression();
            tableExpression.setField(code.getText());
            tableExpression.setRename("t1");
            tableExpression.setJoin("master");
            tableExpression.setOn("");
            List<TableExpression> tableExpressions = new ArrayList<>();
            tableExpressions.add(tableExpression);
            map.put("tbList", tableExpressions);
            Element columnsEls = tableElement.element(new QName("Columns", cNamespace));
            if (columnsEls==null){
                continue;
            }
            List<FieldExpression> fieldExpressions = new ArrayList<>();
            //解析column
            List<Element> columns = columnsEls.elements(new QName("Column", oNamespace));
            for (Element columnEle : columns) {
                Element cname = columnEle.element(new QName("Name", aNamespace));
                Element ccode = columnEle.element(new QName("Code", aNamespace));
                FieldExpression fieldExpression = new FieldExpression();
                fieldExpression.setField("t1."+ccode.getText());
                fieldExpression.setCnname(cname.getText());
                fieldExpression.setRename(camelCaseName(ccode.getText()));
                fieldExpressions.add(fieldExpression);
            }
            map.put("fdList",fieldExpressions);
            map.put("gbList",new ArrayList<String>());
            list.add(map) ;
            createFile(path,code.getText()+".json", map);
        }
        return list;
    }


    /**
     * 读取tables元素列表
     */
    public static List<Element> readerPdm(String pathName) throws Exception {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(new File(pathName));
        Element rootElement = document.getRootElement();

        //读取根节点
        Element rootObject = rootElement.element(new QName("RootObject", oNamespace));
        Element children = rootObject.element(new QName("Children", cNamespace));
        Element model = children.element(new QName("Model", oNamespace));
        List<Element> tableEles = new ArrayList<>();

        //解析package
        Element packagesEle = model.element(new QName("Packages", cNamespace));
        if (packagesEle != null) {
            List<Element> packageEles = packagesEle.elements(new QName("Package", oNamespace));
            for (Element packageEle : packageEles) {
                Element tablesEle = packageEle.element(new QName("Tables", cNamespace));
                if (tablesEle != null) {
                    tableEles.addAll(tablesEle.elements(new QName("Table", oNamespace)));
                }
            }
        }

        //直接解析table
        Element tablesEle = model.element(new QName("Tables", cNamespace));
        if (tablesEle != null) {
            tableEles.addAll(tablesEle.elements(new QName("Table", oNamespace)));
        }

        return tableEles;
    }


    /**
     * 下划线 转换为驼峰
     */
    public static String camelCaseName(String underscoreName) {
        StringBuilder result = new StringBuilder();
        if (underscoreName != null && underscoreName.length() > 0) {
            boolean flag = false;
            for (int i = 0; i < underscoreName.length(); i++) {
                char ch = underscoreName.charAt(i);
                if ("_".charAt(0) == ch) {
                    flag = true;
                } else {
                    if (flag) {
                        result.append(Character.toUpperCase(ch));
                        flag = false;
                    } else {
                        result.append(ch);
                    }
                }
            }
        }
        return result.toString();
    }


    private static void createFile(String path, String name, Map<String,Object> dataMap){
        try {
            String x =  FreemarkerUtil.parseTpl("json.ftl",dataMap) ;
            File jsonFile = new File(path,name);
            //FileOutputStream fileOutputStream = new FileOutputStream(jsonFile);
            FileWriter fileWriter = new FileWriter(jsonFile);
            fileWriter.write(x);
            fileWriter.flush();
            fileWriter.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String pathName = "D:\\01Project\\uchain重构\\uchain2.0.pdm" ;
        String path = "E:\\json\\new" ;
        try {
            List<Element> elementList = PDMXmlUtil.readerPdm(pathName) ;
//            PDMXmlUtil.buildJson(path, elementList);
            PDMXmlUtil.buildExp(path, elementList) ;
            //String x = FreemarkerUtil.parseTpl("json.ftl",dataMap) ;
            //System.out.println(x);
        } catch (Exception e){
            e.printStackTrace();
        }
        // hutool excelUtils test
//        String path = "F:\\" ;
//        ExcelWriter writer = null;
//        OutputStream out = null;
//        List<Map<String,Object>> data = new ArrayList<>() ;
//        for (int id=0;id<10;id++){
//            Map<String, Object> dataRow = new HashMap<>();
//            dataRow.put("a",1+id) ;
//            dataRow.put("b",2) ;
//            dataRow.put("c",3);
//            data.add(dataRow);
//        }
//        System.out.println(data.size());
//        try {
//            writer = ExcelUtil.getBigWriter();
//            writer.addHeaderAlias("a", "AAA");
//            writer.addHeaderAlias("b", "BBB");
//            File file = new File(path,"afd.xlsx");
//            out = new FileOutputStream(file);
//            writer.setOnlyAlias(true);
//            writer.write(data, true) ;
//            for (int j=0; j<5 ;j++){
//                addData(writer, out);
//            }
//            writer.flush(out);
//            // 关闭writer，释放内存
//            writer.close();
//            writer = null;
//        } catch (IOException e){
//            e.printStackTrace();
//            System.out.println("createFile error..");
//        } catch (Exception e){
//            e.printStackTrace();
//        } finally {
//            if (writer!=null){
//                writer.close();
//            }
//            if (out!=null){
//                IOUtils.closeQuietly(out);
//            }
//        }

    }

//    private static void addData(ExcelWriter writer, OutputStream out){
//        System.out.println("------------");
//        List<Map<String,Object>> data = new ArrayList<>() ;
//        for (int id=0;id<10;id++){
//            Map<String, Object> dataRow = new HashMap<>();
//            dataRow.put("a",10+id) ;
//            dataRow.put("b","x") ;
//            dataRow.put("c","y");
//            data.add(dataRow);
//        }
//        System.out.println(data.size());
//        writer.write(data);
//    }

}
